//Package promise 任务调度
package promise

import (
	"fmt"
	"reflect"
	"runtime"
	"time"

	"io/ioutil"
	"net/http"

	"gitee.com/wang_cyi/TryEverything/public"
	"github.com/jakecoffman/cron"
)

// CmdFunc CmdFunc
type CmdFunc func(string) int

// CmdJob CmdJob
type CmdJob struct {
	Param string
	Func  CmdFunc
}

// Run Run
func (c CmdJob) Run() {
	c.Func(c.Param)
}

// Task is Task
type Task struct {
	ID       interface{}       // 任务的唯一标识
	CallBack func(interface{}) // 回调函数
	Param    interface{}       // 回调函数参数,包括普通的函数
}

//NewTask is new
func NewTask(param interface{}) *Task {
	return &Task{
		ID:       nil,
		CallBack: nil,
		Param:    param,
	}
}

//  run is start
func (ts *Task) run() {

	ts.CallBack(ts.Param) //执行任务

}

// Scheduling 守护进程服务对象
//https://github.com/shiguanghuxian/go-daemon/blob/master/godaemon/godaemon.go
//https://github.com/prprprus/scheduler/blob/master/README-zh.md
//https://github.com/go-vgo/robotgo
type Scheduling struct {
	TaskMsg *Task
}

//NewScheduling NewScheduling
func NewScheduling(task *Task) *Scheduling {
	return &Scheduling{
		TaskMsg: task,
	}
}

//WindowTaskPlan 方式1-利用window任务计划 提供的调度-手工配置
func (plan *Scheduling) WindowTaskPlan() {

}

//CronTab 方式2 周期执行 后续参考这个实现https://github.com/lwl1989/timing
func (plan *Scheduling) CronTab() bool {

	if plan.TaskMsg == nil {
		return false
	}
	fn := reflect.ValueOf(plan.TaskMsg.Param)

	if fn.Kind() != reflect.Func {
		fmt.Println("type: ", reflect.TypeOf(plan.TaskMsg.Param))
		return false
	}

	aChan := make(chan int, 1)
	//100分钟一次。
	ticker := time.NewTicker(time.Second * 60 * 100)

	go func() {
		for {
			select {
			case <-ticker.C:
				fmt.Printf("ticked at %v\n", time.Now())
				fn.Call(nil)
			}
		}

	}()
	//阻塞主线程
	<-aChan

	return true

}

//ContentTask is task
type ContentTask struct {
	content string
}

//Run is start
func (t ContentTask) Run() {

	public.SendMailBy163(t.content)
	public.WeiboDailyThinking(t.content)
	SendMsgToWechat(t.content)

}

//ContentTaskTwo is task
type ContentTaskTwo struct {
	content string
	title   string
}

//Run is start
func (t ContentTaskTwo) Run() {

	public.SendMailBy163(t.content)
	public.WeiboDailyThinking(t.content)
	//SendMsgToWechat(t.title)

}

//ContentTaskParam is ContentTaskParam
type ContentTaskParam struct {
	content string
	Type    int //
}

//Run is Run
func (t ContentTaskParam) Run() {
	if t.Type == PUSHTYPEEMAIL {
		public.SendMailBy163(t.content)
	} else if t.Type == PUSHTYPMYSQL {
		SendHoureDReport(t.content)
	} else {
		public.SendMailBy163(t.content)
		public.WeiboDailyThinking(t.content)
	}

}

//DailyPlan 系统之美 每天必做的事情提醒
func DailyPlan(messagesQue chan string, cfg public.Config) {
	cron := cron.New()
	plan := Plan{
		MConfig: cfg,
	}
	var msg string
	//系统之美--每日提醒
	if runtime.GOOS == "linux" {

		/////////////////////////////////////起床吃饭/////////////////////////////////////
		msg = GenDailyTipAt6()
		title := "每天六点固定流程起床：冥想,洗刷，朗读"
		cron.AddJob("0 30 6 * * *", ContentTaskTwo{msg, title}, title)

		msg = plan.AlgorithmPlan()
		cron.AddJob("0 01 7 * * *", ContentTaskParam{msg, PUSHTYPEEMAIL}, "15分钟")

		//msg = plan.keepPlan()
		//cron.AddJob("0 30 7 * * *", ContentTaskParam{msg, PUSHTYPEEMAIL}, "随时可以做")

		/////////////////////////////////////上班任务清单/////////////////////////////////////
		msg = plan.ProjectCheck()
		cron.AddJob("0 10 7 * * *", ContentTaskParam{msg, PUSHTYPEEMAIL}, msg)

		msg = GenDailyTipForMood()
		cron.AddJob("0 30 14 * * *", ContentTaskParam{msg, PUSHTYPEEMAIL}, "坐姿纠正")

		/////////////////////////////////////下班检测清单17点/////////////////////////////////////
		//下班检测清单： 耳机和充电器必须留在公司。带回家100%成为上床看手机的导火索，历史统计：出现1000次，并且每次都没有控制住
		//msg = plan.CheckToday()
		//cron.AddJob("0 30 17 * * *", ContentTaskParam{msg, PUSHTYPEEMAIL}, msg)

		/////////////////////////////////////下班回家/////////////////////////////////////

		msg = plan.EasyAndHard()
		cron.AddJob("0 10 17 * * *", ContentTask{msg}, "21点关闭电脑，放下手机")

		msg = plan.GenDailyTip()
		cron.AddJob("0 30 17 * * *", ContentTask{msg}, "21点关闭电脑，放下手机")
		msg = plan.eatPlan()

		cron.AddJob("0 45 17 * * *", ContentTask{msg}, "吃饭提醒 中午和晚上")
		cron.AddJob("0 30 11 * * *", ContentTask{msg}, "吃饭提醒 中午和晚上")

		//周报提醒
		msg = "提醒：每周六提交周报，读书记录 技术和非技术 这3个输出，不能拖延。"
		cron.AddJob("0 0 17 * * 5", ContentTaskParam{msg, PUSHTYPEEMAIL}, msg)

	} else if runtime.GOOS == "windows" {
		//定时任务--bat提交代码
		githubJob := "0 0 9 * * *"
		cron.AddJob(githubJob, CmdJob{"D:\\local\\update_github.bat", public.RunBatCommand}, "提交代码")

		//定时任务--日报
		//path := "G:\\money\\eye\\work\\daily\\worklog_2020.txt"
		path := plan.MConfig.DailyPath
		cron.AddJob("0 0 10 * * *", DailyTask{TASKTYPEDAY, path, messagesQue, nil}, "每日复盘")
		cron.AddJob("0 25 17 * * *", DailyTask{TASKTYPEDAY, path, messagesQue, nil}, "每日复盘")

		//定时任务--周报
		msg := plan.GenDailReport()
		cron.AddJob("0 0 10 * * 5", ContentTask{msg}, "定时任务--周报")

		//SendHoureDReport
		//小时日报   PUSHTYPMYSQL
		msg = "每天 9 点到 19点"
		cron.AddJob("0 59 9-19 * * *", ContentTaskParam{"D:\\money\\eye\\work\\daily\\work_hour.txt", PUSHTYPMYSQL}, msg)
	}
	cron.Start()
	//bug1 cron语法问题  https://www.gairuo.com/p/cron-expression-sheet

}

//SendMsgToWechat 微信通知提醒
func SendMsgToWechat(msg string) {

	url := "https://sc.ftqq.com/SCU90598T2b431a055e06a253e8bb5ccaef7214ce5e76dc4584592.send"
	url += "?text="
	//url += "每天六点固定流程起床：冥想,洗刷，朗读"
	url += msg
	//url += "& desp="
	//msg = url.QueryEscape(msg)
	//url += msg
	req, err1 := http.NewRequest("GET", url, nil)
	if err1 != nil {
		fmt.Println(err1)
		panic(err1)
	}

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		panic(err)
	}
	defer resp.Body.Close()

	fmt.Println("response Status:", resp.Status)
	fmt.Println("response Headers:", resp.Header)
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println("response Body:", string(body))
}
